//首先引入axios
import axios from 'axios';
import ApiConfig from './filter';
import CryptoJS from 'crypto-js';
// import router from "@/router";
import {useUserStore} from '@/store/modules/user';
// import {usePageStore} from '@/store/modules/page';
import {ElMessage} from 'element-plus';
import { ElLoading } from 'element-plus'


//然后通过create方法来创建一个请求服务
//然后create方法内有一些配置项，比如接口域名`baseURL`、接口请求超时时间`timeout`
//接口url`url`
//接口请求方式`method`等等，需要我们按需传入
// create an axios instance
const service = axios.create({
  baseURL:'/api', // 完整的api地址 = 接口域名+ 接口路径
// 完整url = 服务根url + 请求url拼接的； 服务根url来源于全局变量；请求url来源于api函数的url参数。
  // withCredentials: true, // 跨域请求时发送cookie
  timeout: 5000, // 请求超时时间 5s，请求超时
})
//下面会定义两个拦截器，分别是 `请求拦截器`，`响应拦截器`
//`请求拦截器`是前端请求后端接口前处理的一些逻辑，比如开启loading，配置header请求头等等
//`响应拦截器`就是后端响应我们前端，返回回来的数据，比如我们可以在这响应拦截器内拿到status Code
//拿到后端接口返回的code，关闭loading、根据code码处理一些详细的逻辑等等一系列操作
//request interceptor   请求拦截器  
let loading = null;
service.interceptors.request.use((config)=>{
  if(!config.progress){
      loading = ElLoading.service({
      lock: true,
      text: '加载中',
      background: 'rgba(0, 0, 0, 0.3)',
    });
  }
    let whiteList =  ApiConfig.whiteListApi;
    let url = config.url;
    //判断当前请求是否在白名单中，如果不在，则添加token和秘钥
    if(!whiteList.includes(url)){
      const userStore = useUserStore();
      let token = userStore.token;
      let appSecret = userStore.appSecret;
      config.headers.token = token;
       //添加秘钥
      const timestamp = Date.now().toString(); // 使用毫秒级时间戳提高精度
      config.headers.timestamp = timestamp; // 添加时间戳到请求头
      const message = `${ApiConfig.secretId}:${timestamp}`;
      const secret_key = CryptoJS.HmacSHA256(message,appSecret).toString(CryptoJS.enc.Hex); // 使用HMAC-SHA256进行消息认证码计算，并转换为十六进制字符串
      config.headers.signature = secret_key;
    }
    if(!config.progress){
    loading.close();
    }
    return config;
  },error=>{
    if(!config.progress){
      loading.close();
      }
    return Promise.reject(new Error(error));
  })
// response interceptor  响应拦截器
service.interceptors.response.use(response => {
    const status = response.status.code || 200;
    // if the custom code is not 200, it is judged as an error.// 在这里限定了返回的必须要有返回码——code键，且返回码不为200时视为请求结果错误的 
    if (status !== 200) {
      // 这是错误信息提示
      // 如果返回值有键-message，则错误信息是自定义的返回信息值，否则只提示'Error'
      ElMessage.error(response.status.msg); // 提示错误信息
// 你也可以加入其它一些返回码的判断，也可以根据某些返回码跳转到某些页面
      return Promise.reject(new Error(response.status.msg || 'Error'));
    }
    if(loading)
    loading.close();
    return response.data;
  },
  error => {
    if(loading)
    loading.close();
    ElMessage.error(error) // 提示错误信息
    return Promise.reject(error)
  }
)
//做请求节流
let myService = (function(){
  let hasRequest = [];
  return function(config){
    let url = config.url;
    if(hasRequest.indexOf(url)>-1){
      return Promise.reject(new Error('请求太频繁了'))
    }
    hasRequest.push(url);
    return service({...config}).then(res=>{
      hasRequest.splice(hasRequest.indexOf(url),1);
      return res;
    })
  }
})();
// 最后暴露我们声明的 service 服务
export {
  myService as modService,
  service as initService
}